/*******************************************
 * Copyright 2007 Aphrodite Framework for javaME .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * Email : owner@aphroditeme.dev.java.net
 * Contributors:
 *     Kent Elton - initial API and implementation
 *******************************************/

package com.aphrodite.io.comm;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.SocketConnection;

/**
 * Telnet connection API
 * <p>
 * <b>Establishing a Telnet Connection</b>
 * 
 * <pre>
 * TelnetConnection telnetCon = new TelnetConnection(&quot;192.168.1.1&quot;);
 * ..
 * telnetCon.connect();
 * ..
 * telnetCon.addListener(&lt;==TelnetListener==&gt;&gt;);
 * </pre>
 * 
 * </p>
 * 
 * @author kentelt
 * 
 */
class TelnetConnection extends CommConnection {

	private SocketConnection connection;
	private DataInputStream input;
	private String lastReceived;
	private Vector listener = new Vector();
	private DataOutputStream output;
	private String serverAddr;
	private String terminalBuffer;

	public TelnetConnection(String serverAddress) {
		this.serverAddr = serverAddress;
		terminalBuffer = new String("");
		lastReceived = new String("");
		connection = null;
		input = null;
		output = null;

	}

	public void addListener(TelnetListener lis) {
		listener.addElement(lis);
	}

	private byte[] detokenize(byte abyte0[]) {
		Vector vector = new Vector();
		Vector vector1 = new Vector();
		for (int i = 0; i < abyte0.length; i++)
			if (abyte0[i] == -1) {
				vector.addElement(new Byte(abyte0[i]));
				vector.addElement(new Byte(abyte0[i + 1]));
				vector.addElement(new Byte(abyte0[i + 2]));
				i += 2;
			} else {
				vector1.addElement(new Byte(abyte0[i]));
			}

		byte abyte1[] = new byte[vector.size()];
		for (int j = 0; j < vector.size(); j++) {
			Byte byte1 = (Byte) vector.elementAt(j);
			abyte1[j] = byte1.byteValue();
		}

		abyte0 = new byte[vector1.size()];
		if (vector1.size() > 0) {
			for (int k = 0; k < vector1.size(); k++) {
				Byte byte2 = (Byte) vector1.elementAt(k);
				abyte0[k] = byte2.byteValue();
				System.out.println(k + ":" + abyte0[k]);
			}

			lastReceived += new String(abyte0);
			terminalBuffer += lastReceived;
			for (int i = 0; i < listener.size(); i++) {
				((TelnetListener) listener.elementAt(i)).onDataReceived(lastReceived);
			}
		}
		return abyte1;
	}

	public void disconnect() throws IOException {
		input.close();
		output.close();
		connection.close();
		isConnected = false;
	}

	private byte[] parseRequest(byte abyte0[]) {
		byte abyte1[] = new byte[abyte0.length];
		System.out.println(abyte0.length);
		for (int i = 0; i < abyte0.length; i++) {
			if (abyte0[i] == -3 || abyte0[i] == -2)
				abyte1[i] = -4;
			else if (abyte0[i] == -5)
				abyte1[i] = -3;
			else if (abyte0[i] == -4)
				abyte1[i] = -2;
			else
				abyte1[i] = abyte0[i];
			if (abyte1[i] < 0)
				System.out.println("Wrote byte: " + (256 + abyte1[i]));
			else
				System.out.println("Wrote byte: " + abyte1[i]);
		}

		return abyte1;
	}

	public void removeAllListeners() {
		listener.removeAllElements();
	}

	public void removeListener(TelnetListener lis) {
		listener.removeElement(lis);
	}

	public void run() {
		try {
			connection = (SocketConnection) Connector.open("socket://" + serverAddr + ":23");
			input = new DataInputStream(connection.openInputStream());
			output = new DataOutputStream(connection.openOutputStream());
			isConnected = true;
			System.out.println("Connected");

			do {
				int i = 0;
				do
					i = input.available();
				while (i == 0);
				byte abyte0[] = new byte[i];
				input.read(abyte0, 0, i);
				byte abyte1[] = detokenize(abyte0);
				abyte1 = parseRequest(abyte1);
				System.out.println("Terminal buffer: " + lastReceived);
				System.out.println("OK");
				output.write(abyte1, 0, abyte1.length);
			} while (isConnected);
		} catch (IOException ioe) {
			isConnected = false;
			// System.out.println(ioexception1);
			for (int i = 0; i < listener.size(); i++) {
				((TelnetListener) listener.elementAt(i)).onDataReceived(ioe.toString());
			}
		} catch (IllegalArgumentException iae) {
			isConnected = false;
			for (int i = 0; i < listener.size(); i++) {
				((TelnetListener) listener.elementAt(i)).onDataReceived(iae.toString());
			}
		}
	}

	public boolean send(String s) {
		try {
			byte abyte0[] = s.getBytes();
			output.write(abyte0, 0, abyte0.length);
		} catch (IOException ioe) {
			for (int i = 0; i < listener.size(); i++) {
				((TelnetListener) listener.elementAt(i)).onDataReceived(ioe.toString());
			}
			return false;
		}
		return true;
	}

}
